{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 多层感知机的简洁实现\n",
    "\n",
    "下面我们使用Gluon来实现上一节中的多层感知机。首先导入所需的包或模块。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import d2lzh as d2l\n",
    "from mxnet import gluon, init\n",
    "from mxnet.gluon import loss as gloss, nn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义模型\n",
    "\n",
    "和softmax回归唯一的不同在于，我们多加了一个全连接层作为隐藏层。它的隐藏单元个数为256，并使用ReLU函数作为激活函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "attributes": {
     "classes": [],
     "id": "",
     "n": "5"
    }
   },
   "outputs": [],
   "source": [
    "net = nn.Sequential()\n",
    "net.add(nn.Dense(256, activation='relu'),\n",
    "        nn.Dense(10))\n",
    "net.initialize(init.Normal(sigma=0.01))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据并训练模型\n",
    "\n",
    "我们使用与[“softmax回归的简洁实现”](softmax-regression-gluon.ipynb)一节中训练softmax回归几乎相同的步骤来读取数据并训练模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "attributes": {
     "classes": [],
     "id": "",
     "n": "6"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 1, loss 0.7917, train acc 0.708, test acc 0.785\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 2, loss 0.4891, train acc 0.819, test acc 0.842\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 3, loss 0.4276, train acc 0.841, test acc 0.854\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 4, loss 0.3934, train acc 0.854, test acc 0.859\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch 5, loss 0.3692, train acc 0.863, test acc 0.875\n"
     ]
    }
   ],
   "source": [
    "batch_size = 256\n",
    "train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)\n",
    "\n",
    "loss = gloss.SoftmaxCrossEntropyLoss()\n",
    "trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.5})\n",
    "num_epochs = 5\n",
    "d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, None,\n",
    "              None, trainer)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 小结\n",
    "\n",
    "* 通过Gluon可以更简洁地实现多层感知机。\n",
    "\n",
    "## 练习\n",
    "\n",
    "* 尝试多加入几个隐藏层，对比上一节中从零开始的实现。\n",
    "* 使用其他的激活函数，看看对结果的影响。\n",
    "\n",
    "\n",
    "\n",
    "## 扫码直达[讨论区](https://discuss.gluon.ai/t/topic/738)\n",
    "\n",
    "![](../img/qr_mlp-gluon.svg)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}